﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MacomberMapSystem.Common.Properties;
using MacomberMapSystem.Common.Processing;
using System.Drawing;
using MacomberMapSystem.Common.User_Interfaces.One_Lines;
using System.Windows.Forms.VisualStyles;

namespace MacomberMapSystem.Common.User_Interfaces.Processing
{
    /// <summary>
    /// This class provides a checkbox w/ progress
    /// </summary>
    public class MM_Progress_Checkbox: CheckBox
    {
        #region Variable declarations
        /// <summary>Whether the checkbox has options to be configured</summary>
        private bool _HasOptions;

        /// <summary>Whether the checkbox has options to be configured</summary>
        public bool HasOptions
        {
            get { return _HasOptions; }
            set
            {
                _HasOptions = value;
                if (_HasOptions)
                    this.Image = Resources.PropertiesHS;
                else
                    this.Image = null;
                
            }
        }


        /// <summary>The property object </summary>
        public Object PropertyObject;

        /// <summary>The event handler for property clicks</summary>
        public event MouseEventHandler PropertyClicked;

        /// <summary>Our associated process</summary>
        public CIM_Processor AssociatedProcess;
        #endregion


        #region Initialization
        /// <summary>
        /// Initalize a new checkbox
        /// </summary>
        /// <param name="AssociatedProcess">The process associated with our element</param>
        public MM_Progress_Checkbox(CIM_Processor AssociatedProcess)
        {
            this.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.AssociatedProcess = AssociatedProcess;
        }
        #endregion

        #region Click handling
        /// <summary>
        /// When the user clicks the mouse on the property icon, handle accordingly.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseClick(MouseEventArgs e)
        {
            //Determine whether the user has clicked directly on the checkbox
            using (Graphics g = Graphics.FromHwnd(this.Handle))
            {
                CheckBoxState BoxState = this.Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
                Size Glyph = CheckBoxRenderer.GetGlyphSize(g, BoxState);
                Rectangle DrawBounds = new Rectangle(Glyph.Width + 1, 0, DisplayRectangle.Width - Glyph.Width - (_HasOptions ? Image.Width + 6 : 2), DisplayRectangle.Height - 1);
                Rectangle CheckBounds = new Rectangle(0, (DrawBounds.Height - Glyph.Height) / 2, Glyph.Width, Glyph.Height);
                if (!CheckBounds.Contains(e.Location))                
                    this.Checked ^= true;
            }
            if (PropertyClicked != null)
                PropertyClicked(this, e);
            base.OnMouseClick(e);
        }
        
        #endregion

        /// <summary>
        /// When we refresh our control, draw it as needed
        /// </summary>
        /// <param name="pevent"></param>
        protected override void OnPaint(PaintEventArgs pevent)
        {
            CheckBoxState BoxState = this.Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;

            //Draw our background            
            using (SolidBrush sB = new SolidBrush(this.BackColor))
                pevent.Graphics.FillRectangle(sB, pevent.ClipRectangle);            
            Size Glyph = CheckBoxRenderer.GetGlyphSize(pevent.Graphics, BoxState);
            

            


            //Determine our bounds for drawing the image
            Rectangle DrawBounds = new Rectangle(Glyph.Width + 1, 0, DisplayRectangle.Width - Glyph.Width - (_HasOptions ? Image.Width + 6: 2), DisplayRectangle.Height-1);

            //If we're in progress, draw our rectangle
            if (AssociatedProcess.Progress > 0)
                pevent.Graphics.FillRectangle(Brushes.LightBlue, DrawBounds.Left, DrawBounds.Top, (int)Math.Ceiling(AssociatedProcess.Progress * (float)DrawBounds.Width), DrawBounds.Height);

            //Determine our text color
            Brush DrawBrush = Brushes.Black;
            if (AssociatedProcess.State == CIM_Processor.enumProcessState.Completed)
                DrawBrush = Brushes.MediumSeaGreen;
            else if (AssociatedProcess.State == CIM_Processor.enumProcessState.CompletedWithWarnings)
                DrawBrush = Brushes.Yellow;
            else if (AssociatedProcess.State == CIM_Processor.enumProcessState.CompletedWithErrors || AssociatedProcess.State == CIM_Processor.enumProcessState.FailedWithErrors)
                DrawBrush = Brushes.Red;

            int MarqueeTime = 3;
            using (StringFormat sF = new StringFormat(StringFormatFlags.NoWrap))
            {
                sF.LineAlignment = StringAlignment.Center;

                if (AssociatedProcess.State == CIM_Processor.enumProcessState.Running && DateTime.Now.Second % (MarqueeTime * 2) < MarqueeTime)
                {
                    TimeSpan RunTime = DateTime.Now - AssociatedProcess.StartTime;
                    Double Rem = (RunTime.TotalSeconds * (1 - AssociatedProcess.Progress)) / AssociatedProcess.Progress;
                    String RemStr = "Infinite";
                    if (Rem < TimeSpan.MaxValue.TotalSeconds)
                    {
                        TimeSpan RemainingTime = TimeSpan.FromSeconds(Rem);
                        RemStr = RemainingTime.TotalHours.ToString("00") + ":" + RemainingTime.Minutes.ToString("00") + ":" + RemainingTime.Seconds.ToString("00");
                    }
                    pevent.Graphics.DrawString(AssociatedProcess.State.ToString().Replace('_', ' ') + " " + AssociatedProcess.Progress.ToString("0.0%") + " | " + RemStr, this.Font, DrawBrush, DrawBounds, sF);
                }
                else
                    pevent.Graphics.DrawString(this.Text, this.Font, DrawBrush, DrawBounds, sF);
            }
        




            //Now, draw our checkbox
            CheckBoxRenderer.DrawCheckBox(pevent.Graphics, new Point(0, (DrawBounds.Height-Glyph.Height)/2), BoxState);


            
            //If requested, draw our image
            if (_HasOptions)
                pevent.Graphics.DrawImageUnscaledAndClipped(Image,new Rectangle(DisplayRectangle.Width - Image.Width - 3, (DisplayRectangle.Height - Image.Height-2)/ 2, Image.Width, Image.Height));



            
        }

       
        
    }
}
